﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace Algorithm_api.calculate.twentyfour
{
    public class Calculate24
    {
        public TwentyFourResult Is24(double[] nums)
        {
            TwentyFourResult result = new TwentyFourResult();
            for(int op1 = 1; op1 <= 4; op1++)
            {
                for (int op2 = 1; op2 <= 4; op2++)
                {
                    for(int op3 = 1; op3 <= 4; op3++) //三次操作符
                    {
                        for(int i = 1; i <= 3; i++) // 选定第一个数与后面哪个数先计算
                        {
                            double res1 = calculate(nums[0], nums[i], op1);
                            double[] temp1 = new double[3];
                            temp1[0] = res1;
                            int indx = 1;
                            for(int index = 1; index <= 3; index++) //将剩下两个数按顺序放入数组中
                            {
                                if (index != i)
                                {
                                    temp1[indx] = nums[index];
                                    indx++;
                                }
                            }

                            for(int index = 1; index<= 2; index++)
                            {
                                double res2 = calculate(temp1[0], temp1[index], op2);//计算第二个数
                                double fin = 0.0;
                                double res3 = 0.0;
                                if(index == 1)
                                {
                                    fin = temp1[2];
                                    res3 = calculate(res2, temp1[2], op3);
                                }else
                                {
                                    fin = temp1[1];
                                    res3 = calculate(res2, temp1[1], op3);
                                }//计算出结果
                                if(res3 == 24) // 如果是24 找出排列组合
                                {
                                    result.is24 = true;
                                    string res;
                                    if((op1 == 1 || op1 == 2) && (op2 == 3 || op2 == 4))//第一个操作符为+- 第二个为*/
                                    {
                                        res = "(" + nums[0] + GetOp(op1) + nums[i] + ")" + GetOp(op2) + temp1[index] + GetOp(op3) + fin;
                                    }
                                    else if((op2 == 1 || op2 == 2) && (op3 == 3 || op3 == 4))
                                    {
                                        res ="("+ nums[0] + GetOp(op1) +  nums[i]  + GetOp(op2) + temp1[index]+ ")" + GetOp(op3) + fin;
                                    }
                                    else
                                    {
                                        res = nums[0] + GetOp(op1) + nums[i] + GetOp(op2) + temp1[index]+ GetOp(op3) + fin;
                                    }
                                    if(IsExit(result.results,res))
                                        result.results.Add(res);
                                } 
                            }
                        }
                    }
                }
            }
            return result;
        }

        public bool IsExit(List<string> list,string res)
        {
            foreach(string s in list)
            {
                if (res == s) return false;
            }
            return true;
        }

        public double calculate(double a, double b, int op)
        {
            switch (op)
            {
                case 1:return (a + b);
                case 2:return (a - b);
                case 3:return (a * b);
                case 4:return (a / b);
                default:return 0;
            }
        }

        public string GetOp(int op)
        {
            switch(op)
            {
                case 1:return "+";
                case 2:return "-";
                case 3:return "*";
                case 4:return "/";
                default:return "";
            }
        }
    }
}
